/*
 *  Copyright 2019-2020 Zheng Jie
 *
 *  Licensed under the Apache License, Version 2.0 (the "License");
 *  you may not use this file except in compliance with the License.
 *  You may obtain a copy of the License at
 *
 *  http://www.apache.org/licenses/LICENSE-2.0
 *
 *  Unless required by applicable law or agreed to in writing, software
 *  distributed under the License is distributed on an "AS IS" BASIS,
 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *  See the License for the specific language governing permissions and
 *  limitations under the License.
 */
package com.fzhucc.modules.appletShow.service;

import cn.hutool.core.util.RandomUtil;
import com.fzhucc.config.FileProperties;
import com.fzhucc.exception.BadRequestException;
import com.fzhucc.modules.appletShow.domain.CmsService;
import com.fzhucc.modules.appletShow.domain.dto.CmsServiceClassifyDto;
import com.fzhucc.modules.appletShow.domain.dto.CmsServiceCodeDto;
import com.fzhucc.modules.appletShow.domain.dto.CmsServiceDto;
import com.fzhucc.modules.appletShow.domain.dto.CmsServiceQueryCriteria;
import com.fzhucc.modules.appletShow.repository.CmsServiceRepository;
import com.fzhucc.modules.appletShow.service.mapstruct.CmsServiceMapper;
import com.fzhucc.modules.system.service.DictDetailService;
import com.fzhucc.modules.system.service.DictService;
import com.fzhucc.modules.system.service.UserService;
import com.fzhucc.modules.system.service.dto.DictDetailDto;
import com.fzhucc.modules.system.service.dto.DictDto;
import com.fzhucc.modules.system.service.dto.DictQueryCriteria;
import com.fzhucc.modules.system.service.dto.UserDto;
import com.fzhucc.modules.thinktank.domain.dto.AllBindDto;
import com.fzhucc.utils.*;
import lombok.RequiredArgsConstructor;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletResponse;
import java.io.File;
import java.io.IOException;
import java.util.*;

import static com.fzhucc.modules.appletShow.domain.CmsService.*;

/**
 * @author yyg
 * @website https://eladmin.vip
 * @description 服务实现
 * @date 2022-11-16
 **/
@Service
@RequiredArgsConstructor
public class CmsServiceService {

    private final FileProperties properties;

    private final WxClient wxClient;

    private final RedisUtils redisUtils;

    private final CmsServiceRepository serviceRepository;
    private final CmsServiceMapper serviceMapper;

    private final UserService userService;

    private final DictService dictService;

    private final DictDetailService dictDetailService;

    public Map<String, Object> queryAll(CmsServiceQueryCriteria criteria, Pageable pageable) {
        Page<CmsService> page = serviceRepository.findAll((root, criteriaQuery, criteriaBuilder) -> QueryHelp.getPredicate(root, criteria, criteriaBuilder), pageable);
        Page<CmsServiceDto> map = page.map(serviceMapper::toDto);
        List<CmsServiceDto> list = map.getContent();
        for (CmsServiceDto dto : list) {
            if (dto != null && dto.getCreateUserId() != null) {
                Long createUserId = dto.getCreateUserId();
                UserDto userDto = userService.findById(createUserId);
                if (userDto != null) {
                    dto.setCreateUser(userDto);
                }
            }
        }
        return PageUtil.toPage(map);
    }

    public List<CmsServiceDto> queryAll(CmsServiceQueryCriteria criteria) {
        return serviceMapper.toDto(serviceRepository.findAll((root, criteriaQuery, criteriaBuilder) -> QueryHelp.getPredicate(root, criteria, criteriaBuilder)));
    }

    public CmsServiceDto findById(Integer id) {
        CmsService appletShow = serviceRepository.findById(id).orElseGet(CmsService::new);
        ValidationUtil.isNull(appletShow.getId(), "PService", "id", id);
        return serviceMapper.toDto(appletShow);
    }

    @Transactional(rollbackFor = Exception.class)
    public CmsServiceDto create(CmsServiceDto dto) {
        CmsService resources = new CmsService();
        Long userId = SecurityUtils.getCurrentUserId();
        if (userId == null) {
            throw new BadRequestException("用户ID未找到");
        }
        CmsService entity = serviceMapper.toEntity(dto);
        return serviceMapper.toDto(serviceRepository.save(entity));
    }

    @Transactional(rollbackFor = Exception.class)
    public void update(CmsServiceDto dto) {
        //CmsService resources = new CmsService();
        CmsService entity = serviceRepository.findById(dto.getId()).orElseGet(CmsService::new);
        ValidationUtil.isNull(entity.getId(), "PService", "id", dto.getId());
        entity.copy(serviceMapper.toEntity(dto));
        serviceRepository.save(entity);
    }

    public void deleteAll(Integer[] ids) {
        for (Integer id : ids) {
            serviceRepository.deleteById(id);
        }
    }

    public List<DictDetailDto> getType() {
        DictQueryCriteria dictQueryCriteria = new DictQueryCriteria();
        dictQueryCriteria.setBlurry("cms_service_classify");
        List<DictDto> list = dictService.queryAll(dictQueryCriteria);
        if (list != null && list.size() == 1) {
            List<DictDetailDto> list1 = dictDetailService.getDictByDictId(list.get(0).getId());
            return list1;
        }
        return null;
    }

    /**
     * 生成服务id跳转码。二维码有效时间：30天
     *
     * @param dto
     * @return AllBindDto
     */
    public AllBindDto generateQrCode(CmsServiceCodeDto dto) {
        Integer cmsServiceId = dto.getCmsServiceId();
        //String path = dto.getPath();
        String path = "pages/serve/moreList/serveProjectDetail";
        if (!serviceRepository.existsById(cmsServiceId)) {
            throw new BadRequestException("服务[id:" + cmsServiceId + "]不存在");
        }
        String pathnew = path + "?id=" + cmsServiceId;
        String idstr = Integer.toString(cmsServiceId);
        String code = RandomUtil.randomString(6);
        String qrcode = wxClient.generateMpQr(
                path,
                "id="+idstr+"&type=xq&code=" + code
        );
        /*String qrcode = wxClient.generateMpQrWithNoParm(
                pathnew
        );*/
        String url = wxClient.generateUrlLink(
                path,
                "id="+idstr+"&type=xq&code=" + code,
                //"id="+idstr,
                1689908440000L
        );
        //redisUtils.set("cmsService:bind:" + code, cmsServiceId, 1689908440);
        AllBindDto dto2 = new AllBindDto();
        dto2.setExpireTime(1689908440000L);
        dto2.setQrcode(qrcode);
        dto2.setUrl(url);
        return dto2;
    }

    public CmsServiceClassifyDto getCountByClassify() {
        CmsServiceClassifyDto cmsServiceClassifyDto = new CmsServiceClassifyDto();
        int intellectual_property = serviceRepository.findByClassify(CLASSIFY_INTELLECTUAL_PROPERTY);
        int financial_financing = serviceRepository.findByClassify(CLASSIFY_FINANCIAL_FINANCING);
        int specialization_novelty = serviceRepository.findByClassify(CLASSIFY_SPECIALIZATION_NOVELTY);
        int specialization_entrepreneurship_incubation = serviceRepository.findByClassify(CLASSIFY_ENTREPRENEURSHIP_INCUBATION);
        int specialization_technology = serviceRepository.findByClassify(CLASSIFY_TECHNOLOGY);
        int specialization_other = serviceRepository.findByClassify(CLASSIFY_OTHER);
        cmsServiceClassifyDto.setClassify_intellectual_property(intellectual_property);
        cmsServiceClassifyDto.setClassify_financial_financing(financial_financing);
        cmsServiceClassifyDto.setClassify_specialization_novelty(specialization_novelty);
        cmsServiceClassifyDto.setClassify_entrepreneurship_incubation(specialization_entrepreneurship_incubation);
        cmsServiceClassifyDto.setClassify_technology(specialization_technology);
        cmsServiceClassifyDto.setClassify_other(specialization_other);
        return cmsServiceClassifyDto;
    }

    public void download(List<CmsServiceDto> all, HttpServletResponse response) throws IOException {
        List<Map<String, Object>> list = new ArrayList<>();
        for (CmsServiceDto appletShow : all) {
            Map<String, Object> map = new LinkedHashMap<>();
            map.put("名称", appletShow.getName());
            map.put("banner图片", appletShow.getImg());
            map.put("简介", appletShow.getIntro());
            map.put("是否小程序显示", appletShow.getIsShow());
            map.put("显示顺序", appletShow.getSort());
            map.put("创建者user_id", appletShow.getCreateUserId());
            list.add(map);
        }
        FileUtil.downloadExcel(list, response);
    }

    public Map<String, String> douploadpic(MultipartFile multipartFile, Integer id) {
        // 文件大小验证
        FileUtil.checkSize(properties.getAvatarMaxSize(), multipartFile.getSize());
        // 验证文件上传的格式
        String image = "gif jpg png jpeg";
        String fileType = FileUtil.getExtensionName(multipartFile.getOriginalFilename());
        if (fileType != null && !image.contains(fileType)) {
            throw new BadRequestException("文件格式错误！, 仅支持 " + image + " 格式");
        }
        Optional<CmsService> res = serviceRepository.findById(id);
        if (res.isPresent()) {
            CmsService appletShow = res.orElseGet(CmsService::new);
            String oldPath = appletShow.getImg();
            File file = FileUtil.upload(multipartFile, properties.getBanner());
            String path = Objects.requireNonNull(file).getPath();
            String[] files = path.split("file");
            res.get().setImg("/file" + files[1]);
            serviceRepository.save(res.get());
            if (StringUtils.isNotBlank(oldPath)) {
                FileUtil.del(oldPath);
            }
            return new HashMap<String, String>(1) {{
                put("banner", file.getName());
            }};
        }
        return new HashMap<String, String>(1) {{
            put("banner", "fail");
        }};
    }
}